package com.tripwego.client.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.tripwego.shared.dto.ActiviteDto;
import com.tripwego.shared.dto.EtapeDto;

public class EtapeModel {

	private Long id;

	private List<ActiviteModel> listActivite;

	private Integer order;

	private String name;

	private String address;

	private double latitude;

	private double longitude;

	private Date dateDeb;

	private Date dateFin;

	private String travelMode;

	private String iconUrl;

	public static int counter = 0;

	private int markerIndex;

	private boolean firstStep = false;

	private LinkedList<DayModel> listDay = new LinkedList<DayModel>();

	private EtapeModel etapeModelPrec;

	/**
	 * 
	 */
	public EtapeModel() {
		super();
		// setId(new Long(i++));
		markerIndex = counter++;
	}

	public EtapeModel(EtapeDto etapeDto) {
		super();

		setAddress(etapeDto.getAddress());
		setDateDeb(etapeDto.getDateDeb());
		setDateFin(etapeDto.getDateFin());
		setFirstStep(etapeDto.isFirstStep());
		setIconUrl(etapeDto.getIconUrl());
		setId(etapeDto.getId());
		setLatitude(etapeDto.getPosition().getLatitude());
		setLongitude(etapeDto.getPosition().getLongitude());
		setMarkerIndex(etapeDto.getIndexOnMap());
		setName(etapeDto.getName());
		setOrder(etapeDto.getOrder());
		// setTravelMode(etapeDto.getTravelMode());

		listActivite = new ArrayList<ActiviteModel>();

		for (ActiviteDto activiteDto : etapeDto.getListActivite()) {
			ActiviteModel activiteModel = new ActiviteModel(activiteDto);
			listActivite.add(activiteModel);
		}
	}

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the dateDeb
	 */
	public Date getDateDeb() {
		return dateDeb;
	}

	/**
	 * @param dateDeb
	 *            the dateDeb to set
	 */
	public void setDateDeb(Date dateDeb) {
		this.dateDeb = dateDeb;
	}

	/**
	 * @return the dateFin
	 */
	public Date getDateFin() {
		return dateFin;
	}

	/**
	 * @param dateFin
	 *            the dateFin to set
	 */
	public void setDateFin(Date dateFin) {
		this.dateFin = dateFin;
	}

	/**
	 * @return the order
	 */
	public Integer getOrder() {
		return order;
	}

	/**
	 * @param order
	 *            the order to set
	 */
	public void setOrder(Integer order) {
		this.order = order;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the latitude
	 */
	public double getLatitude() {
		return latitude;
	}

	/**
	 * @param latitude
	 *            the latitude to set
	 */
	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	/**
	 * @return the longitude
	 */
	public double getLongitude() {
		return longitude;
	}

	/**
	 * @param longitude
	 *            the longitude to set
	 */
	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}

	/**
	 * @return the markerIndex
	 */
	public int getMarkerIndex() {
		return markerIndex;
	}

	/**
	 * @param markerIndex
	 *            the markerIndex to set
	 */
	public void setMarkerIndex(int markerIndex) {
		this.markerIndex = markerIndex;
	}

	/**
	 * @return the travelMode
	 */
	public String getTravelMode() {
		return travelMode;
	}

	/**
	 * @param travelMode
	 *            the travelMode to set
	 */
	public void setTravelMode(String travelMode) {
		this.travelMode = travelMode;
	}

	/**
	 * @return the iconUrl
	 */
	public String getIconUrl() {
		return iconUrl;
	}

	/**
	 * @param iconUrl
	 *            the iconUrl to set
	 */
	public void setIconUrl(String iconUrl) {
		this.iconUrl = iconUrl;
	}

	/**
	 * @return the address
	 */
	public String getAddress() {
		return address;
	}

	/**
	 * @param address
	 *            the address to set
	 */
	public void setAddress(String address) {
		this.address = address;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "EtapeModel [id=" + id + ", order=" + order + ", name=" + name + ", address=" + address + ", latitude=" + latitude + ", longitude=" + longitude
				+ ", dateDeb=" + dateDeb + ", dateFin=" + dateFin + ", travelMode=" + travelMode + ", iconUrl=" + iconUrl + ", markerIndex=" + markerIndex
				+ "]";
	}

	/**
	 * @return the firstStep
	 */
	public boolean isFirstStep() {
		return firstStep;
	}

	/**
	 * @param firstStep
	 *            the firstStep to set
	 */
	public void setFirstStep(boolean firstStep) {
		this.firstStep = firstStep;
	}

	/**
	 * @return the listDay
	 */
	public LinkedList<DayModel> getListDay() {
		return listDay;
	}

	/**
	 * @param listDay
	 *            the listDay to set
	 */
	public void setListDay(LinkedList<DayModel> listDay) {
		this.listDay = listDay;
	}

	public void initListDay(boolean modif, int nbDayAvantModification) {

		listDay.clear();

		int numberDayPrec = 0;
		int nbDayAffecte = 0;

		if (firstStep) {
			numberDayPrec = 0;
			nbDayAffecte = CalendarUtil.getDaysBetween(dateDeb, dateFin);
		} else {
			numberDayPrec = etapeModelPrec.getListDay().getLast().getNumber();
			nbDayAffecte = CalendarUtil.getDaysBetween(dateDeb, dateFin);
		}

		Date dateEncours = CalendarUtil.copyDate(dateDeb);

		int nbDay;

		if (modif) {
			if (nbDayAvantModification < nbDayAffecte) {
				nbDay = nbDayAffecte;
			} else {
				nbDay = nbDayAvantModification;
			}
		} else {
			nbDay = nbDayAffecte;
		}

		for (int i = 0; i < nbDay; i++) {
			CalendarUtil.addDaysToDate(dateEncours, 1);
			DayModel dayModel = new DayModel(numberDayPrec + 1);
			dayModel.setDate(CalendarUtil.copyDate(dateEncours));

			if (modif) {
				dayModel.setAttacheAEtape(i < nbDayAffecte);
			} else {
				dayModel.setAttacheAEtape(true);
			}

			listDay.add(dayModel);
			numberDayPrec++;
		}

	}

	/**
	 * @return the etapeModelPrec
	 */
	public EtapeModel getEtapeModelPrec() {
		return etapeModelPrec;
	}

	/**
	 * @param etapeModelPrec
	 *            the etapeModelPrec to set
	 */
	public void setEtapeModelPrec(EtapeModel etapeModelPrec) {
		this.etapeModelPrec = etapeModelPrec;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + ((dateDeb == null) ? 0 : dateDeb.hashCode());
		result = prime * result + ((dateFin == null) ? 0 : dateFin.hashCode());
		result = prime * result + ((iconUrl == null) ? 0 : iconUrl.hashCode());
		result = prime * result + ((listDay == null) ? 0 : listDay.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((travelMode == null) ? 0 : travelMode.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		EtapeModel other = (EtapeModel) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (dateDeb == null) {
			if (other.dateDeb != null)
				return false;
		} else if (!dateDeb.equals(other.dateDeb))
			return false;
		if (dateFin == null) {
			if (other.dateFin != null)
				return false;
		} else if (!dateFin.equals(other.dateFin))
			return false;
		if (iconUrl == null) {
			if (other.iconUrl != null)
				return false;
		} else if (!iconUrl.equals(other.iconUrl))
			return false;
		if (listDay == null) {
			if (other.listDay != null)
				return false;
		} else if (!listDay.equals(other.listDay))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (travelMode == null) {
			if (other.travelMode != null)
				return false;
		} else if (!travelMode.equals(other.travelMode))
			return false;
		return true;
	}

	public void cloner(EtapeModel etapeModel) {
		setAddress(etapeModel.getAddress());
		setDateDeb(etapeModel.getDateDeb());
		setDateFin(etapeModel.getDateFin());
		setEtapeModelPrec(etapeModel.getEtapeModelPrec());
		setFirstStep(etapeModel.isFirstStep());
		setIconUrl(etapeModel.getIconUrl());
		setId(etapeModel.getId());
		setLatitude(etapeModel.getLatitude());
		setListDay(etapeModel.getListDay());
		setLongitude(etapeModel.getLongitude());
		setMarkerIndex(etapeModel.getMarkerIndex());
		setOrder(etapeModel.getOrder());
		setTravelMode(etapeModel.getTravelMode());
	}

	/**
	 * @return the listActivite
	 */
	public List<ActiviteModel> getListActivite() {
		return listActivite;
	}

	/**
	 * @param listActivite
	 *            the listActivite to set
	 */
	public void setListActivite(List<ActiviteModel> listActivite) {
		this.listActivite = listActivite;
	}
}
